package com.gr.staffpm.datatypes;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import org.apache.solr.analysis.LowerCaseFilterFactory;
import org.apache.solr.analysis.SnowballPorterFilterFactory;
import org.apache.solr.analysis.StandardTokenizerFactory;
import org.hibernate.annotations.Proxy;
import org.hibernate.search.annotations.Analyzer;
import org.hibernate.search.annotations.AnalyzerDef;
import org.hibernate.search.annotations.DocumentId;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.Parameter;
import org.hibernate.search.annotations.Store;
import org.hibernate.search.annotations.TokenFilterDef;
import org.hibernate.search.annotations.TokenizerDef;

/**
 * Hibernate mapping class for Tasks Table
 * @author Graham Rhodes
 * @date   29 Oct 2010
 */
@Entity
@Proxy(lazy = false)
@Table(name = "tasks")
@Indexed(index = "tasks_name")
@AnalyzerDef(name = "taskanalyzer", tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class), filters = { @TokenFilterDef(factory = LowerCaseFilterFactory.class),
        @TokenFilterDef(factory = SnowballPorterFilterFactory.class, params = { @Parameter(name = "language", value = "English") }) })
public class Task implements Serializable, IDatatype {

    private static final long serialVersionUID = 1L;
    public static final String ID = "taskId";
    public static final String NAME = "name";
    public static final String SUMMARY = "summary";
    public static final String PROJECT = "project";
    public static final String STATUS = "status";
    public static final String IMPORTANCE = "importance";
    public static final String DESCRIPTION = "description";
    public static final String ASSIGNEE = "assignee";
    public static final String DUE_DATE = "dueDate";
    public static final String RESOLVED = "resolved";
    public static final String RESOLVED_BY = "resolvedBy";
    public static final String RESOLVED_DATE = "resolvedDate";
    public static final String CREATED_BY = "createdBy";
    public static final String CREATED = "created";
    public static final String UPDATED_BY = "updatedBy";
    public static final String LAST_UPDATED = "lastUpdated";
    private int taskId = 0;
    private String name = "";
    private String summary = "";
    private String description = "";
    private User assignee = null;
    private TaskStatus status;
    private TaskImportance importance;
    private Project project = null;
    private boolean queued = false;
    private Date dueDate = new Date(Calendar.getInstance().getTimeInMillis());
    private boolean resolved = false;
    private User resolvedBy = null;
    private Date resolvedDate = new Date(Calendar.getInstance().getTimeInMillis());
    private List<TaskComment> comments = new ArrayList<TaskComment>();
    private User createdBy = null;
    private Date created = new Date(Calendar.getInstance().getTimeInMillis());
    private User updatedBy = null;
    private Date lastUpdated = new Date(Calendar.getInstance().getTimeInMillis());

    @Id
    @DocumentId
    @GeneratedValue
    @Column(name = "task_id")
    public int getTaskId() {
        return taskId;
    }

    @Basic
    @Column(name = "name")
    @Field(index = Index.TOKENIZED, store = Store.YES)
    @Analyzer(definition = "taskanalyzer")
    public String getName() {
        return name;
    }

    @Basic
    @Column(name = "summary")
    @Field(index = Index.UN_TOKENIZED, store = Store.NO)
    @Analyzer(definition = "taskanalyzer")
    public String getSummary() {
        return summary;
    }

    @Basic
    @Column(name = "description")
    @Field(index = Index.UN_TOKENIZED, store = Store.NO)
    @Analyzer(definition = "taskanalyzer")
    public String getDescription() {
        return description;
    }

    @ManyToOne
    @JoinColumn(name = "assignee")
    public User getAssignee() {
        return assignee;
    }

    @ManyToOne
    @JoinColumn(name = "status")
    public TaskStatus getStatus() {
        return status;
    }

    @ManyToOne
    @JoinColumn(name = "importance")
    public TaskImportance getImportance() {
        return importance;
    }

    @ManyToOne
    @JoinColumn(name = "project_id")
    public Project getProject() {
        return project;
    }

    @Basic
    @Column(name = "queued")
    public boolean isQueued() {
        return queued;
    }

    @Column(name = "due_date")
    @Temporal(TemporalType.TIMESTAMP)
    public Date getDueDate() {
        return dueDate;
    }

    @Basic
    @Column(name = "resolved")
    public boolean isResolved() {
        return resolved;
    }

    @ManyToOne
    @JoinColumn(name = "resolvedBy")
    public User getResolvedBy() {
        return resolvedBy;
    }

    @Column(name = "resolvedDate")
    @Temporal(TemporalType.TIMESTAMP)
    public Date getResolvedDate() {
        return resolvedDate;
    }

    @OneToMany
    @JoinTable(name = "task_comments", joinColumns = @JoinColumn(name = "comment_id"), inverseJoinColumns = @JoinColumn(name = "task_id"))
    public List<TaskComment> getComments() {
        return comments;
    }

    @ManyToOne
    @JoinColumn(name = "createdBy")
    public User getCreatedBy() {
        return createdBy;
    }

    @Column(name = "created")
    @Temporal(TemporalType.TIMESTAMP)
    public Date getCreated() {
        return created;
    }

    @ManyToOne
    @JoinColumn(name = "updatedBy")
    public User getUpdatedBy() {
        return updatedBy;
    }

    @Column(name = "lastUpdated")
    @Temporal(TemporalType.TIMESTAMP)
    public Date getLastUpdated() {
        return lastUpdated;
    }

    public void setTaskId(int taskId) {
        this.taskId = taskId;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setSummary(String summary) {
        this.summary = summary;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public void setAssignee(User assignee) {
        this.assignee = assignee;
    }

    public void setStatus(TaskStatus status) {
        this.status = status;
    }

    public void setImportance(TaskImportance importance) {
        this.importance = importance;
    }

    public void setProject(Project project) {
        this.project = project;
    }

    public void setQueued(boolean queued) {
        this.queued = queued;
    }

    public void setDueDate(Date dueDate) {
        this.dueDate = dueDate;
    }

    public void setResolved(boolean resolved) {
        this.resolved = resolved;
    }

    public void setResolvedBy(User resolvedBy) {
        this.resolvedBy = resolvedBy;
    }

    public void setResolvedDate(Date resolvedDate) {
        this.resolvedDate = resolvedDate;
    }

    public void setComments(List<TaskComment> comments) {
        this.comments = comments;
    }

    public void setCreatedBy(User createdBy) {
        this.createdBy = createdBy;
    }

    public void setCreated(Date created) {
        this.created = created;
    }

    public void setUpdatedBy(User updatedBy) {
        this.updatedBy = updatedBy;
    }

    public void setLastUpdated(Date lastUpdated) {
        this.lastUpdated = lastUpdated;
    }

    @Transient
    @Override
    public String getDisplayValue() {
        return getName();
    }

}
